﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using System.IO;
using ANGFLib;

namespace ANGFSessionWrapper
{
    [Serializable]
    public class WrapSession : MarshalByRefObject
    {
        public WrapSession()
        {
            State.IsInWebPlayer = true;
            General.ReportError = (message) =>
            {
                throw new ApplicationException(message);
            };
            SystemFile.Load();
            State.SetEquipSet(State.装備なし, new EquipSet());
            // 選択に先立って全てのモジュールのXMLファイルを読み込んで一覧を作る
            //Scenarios.Modules = Scenarios.SeekModulesFromRegistryOnly(null).ToArray();
            var context = new AngfWebPlayer3.Models.MvcBasicContext();
            Scenarios.Modules = context.SchenarioRecords.ToArray().Select(c =>
                {
                    var client = new WebClient();
                    var stream = client.OpenRead(c.ModuleUri);
                    var bb = new BinaryArrayBuilder(stream);
                    using (var reader = new BinaryReader(stream))
                    {
                        for (; ; )
                        {
                            var ar = reader.ReadBytes(1024);
                            if (ar == null || ar.Length == 0) break;
                            bb.AppendArray(ar);
                        }
                    }
                    var tempPath = Path.GetTempFileName();
                    File.WriteAllBytes(tempPath, bb.ToArray());
                    var sep = new ANGFLib.Scenarios.Sep();
                    sep.filename = tempPath;
                    sep.loadSub();
                    var result = new MyXmlDoc();
                    if (!result.LoadFromXDocument(sep.doc, c.ModuleUri.ToString())) return null;
                    result.xmlFilePath = c.ModuleUri.ToString();
                    return result;
                }).ToArray();
        }
        public bool ScenarioThreadIsActive
        {
            get { return ScenarioThread.IsActive; }
        }

        public RawMyXmlDoc[] StartModules()
        {
            //return Scenarios.SeekModulesFromRegistryOnly(null).Where(c => c.startupModule).OrderByDescending(c => SystemFile.GetTimeStamp(c.id)).ToArray();
            return Scenarios.Modules.Where(c => c.startupModule).OrderByDescending(c => SystemFile.GetTimeStamp(c.id)).ToArray();
        }

        public QueueBase[] GetWaitForReady()
        {
            return ScenarioThread.WaitForReady();
        }

        public void ClearRenderingQueue()
        {
            ScenarioThread.RenderingQueue.Clear();
        }

        public void AddRenderingQueue(QueueBase item)
        {
            ScenarioThread.RenderingQueue.Add(item);
        }

        public void StartupSub(string id)
        {
            RawMyXmlDoc f = Scenarios.Modules.First(c=>c.id == id);
            SystemFile.SetLastPlayDateTime(f.id);
            SystemFile.Save();
            string startposId = Scenarios.Load(f as MyXmlDoc);
            Flags.CurrentPlaceId = startposId;
            Flags.CurrentWorldId = Constants.DefaultWordId;
            ScenarioThread.RunScenarioMain();
            //ScenarioThread.AskForUserEvent.WaitOne();
        }

        public string GetSimpleStringResult()
        {
            return ScenarioThread.SimpleStringResult;
        }

        public int GetSimpleMenuResult()
        {
            return ScenarioThread.SimpleMenuResult;
        }

        public void SetSimpleMenuResult(int value)
        {
            ScenarioThread.SimpleMenuResult = value;
        }

        public void SetSimpleStringResult(string value)
        {
            ScenarioThread.SimpleStringResult = value;
        }

        public void WaitAskForUserEvent()
        {
            ScenarioThread.AskForUserEvent.WaitOne();
        }
        public void ContinueEventSet()
        {
            ScenarioThread.ContinueEvent.Set();
        }
    }
}
